//
//  HSInfiniteScrollView.swift
//  HSMainViewControllerHandler
//
//  Created by haisheng huang on 16/1/19.
//  Copyright © 2016年 haisheng huang. All rights reserved.
//

import UIKit
fileprivate func < <T : Comparable>(lhs: T?, rhs: T?) -> Bool {
  switch (lhs, rhs) {
  case let (l?, r?):
    return l < r
  case (nil, _?):
    return true
  default:
    return false
  }
}

fileprivate func > <T : Comparable>(lhs: T?, rhs: T?) -> Bool {
  switch (lhs, rhs) {
  case let (l?, r?):
    return l > r
  default:
    return rhs < lhs
  }
}


class HSInfiniteScrollView: UIView, UIScrollViewDelegate {

    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect) {
        // Drawing code
    }
    */
    
    fileprivate var pageControl: HSPageControl? = nil
    fileprivate var backupData: NSArray? = nil
    fileprivate var autoTimer: Timer? = nil
    fileprivate var autoTimerInterval: TimeInterval? = 0.0
    var scrollView: UIScrollView? = nil
    
    convenience init(frame: CGRect, data:NSArray?, autoInterval:TimeInterval?, type: HSPageControlType){
        
        self.init(frame: frame)
        
        guard data != nil else {return}
        
        //创建scrollView
        self.createScrollView(frame)
        
        //加载scrollView
        self.loadInfiniteScroll(data)
        
        //设置是否自动滚动
        if autoInterval != nil && autoInterval > 0.0 {
            self.startAutoChangeTimer(autoInterval!)
        }
        
        //加载PageControl
        self.loadPageControl(data!.count, type: type)
    }
    
    
    fileprivate func createScrollView(_ frame: CGRect) {
        
        var templeFrame = frame
        templeFrame.origin = CGPoint.zero
        let templeScroll: UIScrollView = UIScrollView(frame: templeFrame)
        self.addSubview(templeScroll)
        
        self.scrollView = templeScroll
        self.scrollView!.showsHorizontalScrollIndicator = false
        self.scrollView!.showsVerticalScrollIndicator = false
        self.scrollView!.isPagingEnabled = true
        self.scrollView!.delegate = self
        
    }
    
    fileprivate func loadInfiniteScroll(_ data: NSArray?) {
        
        guard data?.count != 0 else { return }
        
        for i in 0..<data!.count {
            
            let templeView = self.createCustomItemView(data![i] as AnyObject?)
            var templeFrame = templeView.frame
            templeFrame.origin.x = CGFloat(i + 1) * self.frame.width
            templeFrame.size = self.frame.size
            templeView.frame = templeFrame
            self.scrollView!.addSubview(templeView)
            
        }
        
        let firstView: UIView = self.createCustomItemView(data?.lastObject as AnyObject?)
        var firstFrame = firstView.frame
        firstFrame.origin.x = 0
        firstFrame.size = self.frame.size
        firstView.frame = firstFrame
        self.scrollView!.addSubview(firstView)
        
        let lastView: UIView = self.createCustomItemView(data?.firstObject as AnyObject?)
        var lastFrame = lastView.frame
        lastFrame.origin.x = CGFloat(data!.count + 1) * self.frame.width
        lastFrame.size = self.frame.size
        lastView.frame = lastFrame
        self.scrollView!.addSubview(lastView)
        
        let contentSize = CGSize(width: self.frame.width * CGFloat((data?.count)! + 2), height: self.frame.height)
        self.scrollView!.contentSize = contentSize
        self.scrollView!.contentOffset.x = self.frame.width
        
        self.backupData = data
    }
    
    fileprivate func loadPageControl(_ count: Int, type: HSPageControlType) {
        
        if type != HSPageControlType.none {
            
            let pageControl: HSPageControl = HSPageControl(type: HSPageControlType.rightBottom, superView: self, numberOfPages: count, currentPage: 0)
            pageControl.currentPageIndicatorTintColor = UIColor.blue
            pageControl.pageIndicatorTintColor = UIColor.gray
            self.pageControl = pageControl
        }
    }
    
    func setPageControlIndicator(_ currentColor: UIColor, tintColor: UIColor) {
        
        guard self.pageControl != nil else {
            //print("pageControl is nil!"); 
            return
        }
        
        self.pageControl?.currentPageIndicatorTintColor = currentColor
        self.pageControl?.pageIndicatorTintColor = tintColor
    }
    
    /**
     *  自定义要加载的ItemView
     **/
    func createCustomItemView(_ viewData: AnyObject?) -> UIView {
        
        let view: UIView = UIView()
        view.frame.origin = CGPoint.zero
        view.backgroundColor = viewData as? UIColor
        return view
    }
    
    //Timer 的设置
    func startAutoChangeTimer(_ interval: TimeInterval) {
        
        guard interval > 0.0 else {return}
        
        self.autoTimerInterval = interval
        
        if self.autoTimer != nil {
            self.autoTimer?.invalidate()
            self.autoTimer = nil
        }
        
        self.autoTimer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(HSInfiniteScrollView.movoToTargetPosition), userInfo: nil, repeats: true)
    }
    
    func stopAutoChangeTimer() {
        
        guard self.autoTimer != nil else {return}
        
        self.autoTimer?.invalidate()
        self.autoTimer = nil
        
    }
    
    func pauseAutoChangeTimer() {
        
        self.autoTimer?.fireDate = Date.distantFuture
        
    }
    
    func resumeAutoChangeTimer() {
        self.autoTimer?.fireDate = Date(timeIntervalSinceNow: 2.0)
    }
    
    //NSTimer selector
    func movoToTargetPosition() {
        
        var currentPoint: CGPoint = self.scrollView!.contentOffset
        
        if currentPoint.x == self.frame.width * CGFloat(self.backupData!.count + 1) {
            
            currentPoint.x = self.frame.width
            self.scrollView!.setContentOffset(currentPoint, animated: false)
            
        }
        
        let nextPoint = CGPoint(x: currentPoint.x + self.frame.size.width, y: currentPoint.y)
        
        self.scrollView!.setContentOffset(nextPoint, animated: true)
        
        let currentPage: Int = Int(floor((self.scrollView!.contentOffset.x - self.frame.width/CGFloat(self.backupData!.count + 2))/self.frame.width)) + 1
        
        if currentPage == 0 {
            
            var tempFrame = self.frame
            tempFrame.origin.x = self.frame.width * CGFloat((self.backupData?.count)!)
            self.scrollView!.scrollRectToVisible(tempFrame, animated: false)
            
            if self.pageControl != nil {
                 self.pageControl?.currentPage = (self.backupData?.count)! - 1
            }
            
        } else if currentPage == (self.backupData?.count)! + 1 {
            
            var tempFrame = self.frame
            tempFrame.origin.x = self.frame.width
            
            self.scrollView!.scrollRectToVisible(tempFrame, animated: false)
            
            if self.pageControl != nil {
                 self.pageControl?.currentPage = 0
            }
            
        } else {
            
            if currentPage == self.backupData?.count {
                 self.pageControl?.currentPage = 0
            } else {
                 self.pageControl?.currentPage = currentPage
            }
        }
        
    }
    
    //UIScrollViewDelegate
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        
        let currentPage: Int = Int(floor((self.scrollView!.contentOffset.x - self.frame.width/CGFloat(self.backupData!.count + 2))/self.frame.width)) + 1
        
        if currentPage == 0 {
            
            var tempFrame = self.frame
            tempFrame.origin.x = self.frame.width * CGFloat((self.backupData?.count)!)
            self.scrollView!.scrollRectToVisible(tempFrame, animated: false)
            
            if self.pageControl != nil {
                self.pageControl?.currentPage = (self.backupData?.count)! - 1
            }
            
        } else if currentPage == (self.backupData?.count)! + 1 {
            
            var tempFrame = self.frame
            tempFrame.origin.x = self.frame.width
            
            self.scrollView!.scrollRectToVisible(tempFrame, animated: false)
            
            if self.pageControl != nil {
                self.pageControl?.currentPage = 0
            }
            
        } else {
            
            if self.pageControl != nil {
                self.pageControl?.currentPage = currentPage - 1
            }
        }
        
        self .resumeAutoChangeTimer()
    }
    
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        
        if self.autoTimer != nil {
            self.pauseAutoChangeTimer()
        }
    }
}
